package org.sam.beatles.ui;

import static com.metsci.glimpse.docking.DockingFrameCloseOperation.DISPOSE_ALL_FRAMES;
import static com.metsci.glimpse.docking.DockingThemes.defaultDockingTheme;
import static com.metsci.glimpse.docking.DockingUtils.requireIcon;
import static com.metsci.glimpse.docking.DockingWindowTitlers.createDefaultWindowTitler;
import static com.metsci.glimpse.docking.Side.BOTTOM;
import static com.metsci.glimpse.docking.Side.LEFT;
import static com.metsci.glimpse.docking.ViewCloseOption.VIEW_NOT_CLOSEABLE;
import static java.awt.ComponentOrientation.RIGHT_TO_LEFT;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.apache.commons.lang3.StringUtils;
import org.sam.beatles.MainFrameContainer;
import org.sam.swing.JSPanel;
import org.sam.swing.annotation.Id;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import com.metsci.glimpse.docking.DockingTheme;
import com.metsci.glimpse.docking.MultiSplitPane;
import com.metsci.glimpse.docking.Tile;
import com.metsci.glimpse.docking.TileFactory;
import com.metsci.glimpse.docking.TileFactoryStandard;
import com.metsci.glimpse.docking.View;
import com.metsci.glimpse.docking.group.frame.DockingFrame;
import com.metsci.glimpse.docking.group.frame.DockingGroupMultiframe;

/**
 * 系统的主界面管理容器
 * 
 * @author sam
 *
 */
public class MainFrameContainerImpl implements MainFrameContainer {

	/**
	 * dock分组
	 */
	private DockingGroupMultiframe group;

	/**
	 * dock窗口
	 */
	private DockingFrame frame;

	/**
	 * 拿到viewPart的操作
	 */
	private Map<String, JComponent> viewParts;

	/**
	 * bean工具助手
	 */
	@Autowired
	private ApplicationContext springContext;

	/**
	 * 日志窗口
	 */
	@Id("logPanel")
	private JPanelLog logPanel;

	/**
	 * 默认打开的主界面
	 */
	@Id("welcomePanel")
	private JPanelWelcome welcomePanel;

	/**
	 * 主窗口容器
	 */
	protected Tile mainTile;

	/**
	 * 导航容器
	 */
	protected Tile navigationTile;

	/**
	 * 日志容器
	 */
	protected Tile logTile;

	/**
	 * 日志窗口工具条
	 * 
	 * @return
	 */
	protected JToolBar createLogToolBar() {
		JToolBar toolbar = new JToolBar();
		toolbar.setBorder(null);
		toolbar.setBorderPainted(false);
		toolbar.setFloatable(false);
		toolbar.setRollover(true);
		toolbar.setOpaque(false);
		toolbar.setComponentOrientation(RIGHT_TO_LEFT);
		return toolbar;
	}

	/**
	 * 过滤出需要的构建功能的action对象
	 * 
	 * @param filter
	 * @return
	 */
	protected Map<String, List<OpenDockPanelAction>> getActions(String filter) {
		final String postion = StringUtils.isEmpty(filter) ? OpenDockPanelAction.POSITION_NAVIGATION : filter;
		Map<String, OpenDockPanelAction> beans = springContext.getBeansOfType(OpenDockPanelAction.class);

		Map<String, List<OpenDockPanelAction>> groups = beans.values().stream()
				.filter(n -> postion.equals(n.getPosition()))
				.sorted((n1, n2) -> Integer.compare(n1.getOrder(), n2.getOrder()))
				.collect(Collectors.groupingBy(OpenDockPanelAction::getGroup));

		return groups;
	}

	/**
	 * 生成导航树
	 * 
	 * @return
	 */
	protected JSPanel createNavgation() {
		JSPanel panel = new JSPanel();
		panel.setName("navgation");
		panel.setLayout(new BorderLayout());
		try {
			DefaultMutableTreeNode root = new DefaultMutableTreeNode("管理系统");
			JTree tree = new JTree();
			tree.setName("navgationTree");

			Map<String, List<OpenDockPanelAction>> beans = this.getActions(OpenDockPanelAction.POSITION_NAVIGATION);
			if (beans == null || beans.isEmpty())
				return panel;

			for (Entry<String, List<OpenDockPanelAction>> entry : beans.entrySet()) {
				DefaultMutableTreeNode node = new DefaultMutableTreeNode(entry.getKey());

				for (OpenDockPanelAction action : entry.getValue()) {
					node.add(new DefaultMutableTreeNode(action));
				}
				root.add(node);
			}

			tree.setModel(new DefaultTreeModel(root));
			tree.addMouseListener(new MouseAdapter() {

				@Override
				public void mouseClicked(MouseEvent e) {
					super.mouseClicked(e);
					if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
						DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
						if (node == null || node.getUserObject() == null)
							return;

						if (!(node.getUserObject() instanceof Action))
							return;

						((Action) node.getUserObject())
								.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_FIRST, "double clicked"));
					}
				}
			});
			panel.add(new JScrollPane(tree), BorderLayout.CENTER);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return panel;
	}

	/**
	 * 生成容器部分
	 */
	protected void buildDock() {
		frame = group.addNewFrame();
		MultiSplitPane docker = frame.docker();

		docker.addInitialLeaf(mainTile);
		docker.addNeighborLeaf(navigationTile, mainTile, LEFT, 0.15);
		docker.addEdgeLeaf(logTile, BOTTOM, 0.2);

		frame.pack();
		frame.setLocationByPlatform(true);
		frame.setExtendedState(DockingFrame.MAXIMIZED_BOTH);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/**
	 * 系统初始化方法
	 */
	protected void init() {
		this.viewParts = Collections.synchronizedMap(new HashMap<>());

		final DockingTheme dockingTheme = defaultDockingTheme();

		JSPanel navgationPanel = createNavgation();
		View navgationView = new View(TILE_NAVIGATION, navgationPanel, "基础数据", VIEW_NOT_CLOSEABLE, null,
				requireIcon("webtree.png"), null);

		final String appName = "管理系统";
		group = new DockingGroupMultiframe(DISPOSE_ALL_FRAMES, dockingTheme);
		group.addListener(createDefaultWindowTitler(appName));
		TileFactory tileFactory = new TileFactoryStandard(group);

		// 导航dock部分
		this.navigationTile = tileFactory.newTile();
		this.navigationTile.addView(navgationView, 0);
		this.viewParts.put(navgationView.viewId, this.navigationTile);

		// 主容器部分
		this.welcomePanel = new JPanelWelcome();
		this.welcomePanel.setName("welcomePanel");
		View mainView = new View(TILE_MAIN, welcomePanel, "主界面", VIEW_NOT_CLOSEABLE, null, requireIcon("jframe.png"),
				null);
		this.mainTile = tileFactory.newTile();
		this.mainTile.addView(mainView, 0);

		this.viewParts.put(mainView.viewId, mainTile);

		// 日志窗口
		logPanel = new JPanelLog("logPanel", "仿真日志");
		JToolBar logToolBar = createLogToolBar();

		View logView = new View(TILE_LOG, logPanel, "系统日志", VIEW_NOT_CLOSEABLE, null,
				requireIcon("collapsiblepane.png"), logToolBar);
		logTile = tileFactory.newTile();
		logTile.addView(logView, 0);
		this.viewParts.put(TILE_LOG, logTile);

		this.buildDock();
		
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void launcher() {
		if (frame != null) {
			this.buildDock();
			frame.setVisible(true);
		} else {
			this.init();
			frame.setVisible(true);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void dispose() {
		if (frame != null)
			frame.setVisible(false);
	}

	@Override
	public Map<String, JComponent> getViewParts() {
		return this.viewParts;
	}

}
